#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "emulator_manager.h"
#include <QErrorMessage>
#include <QResizeEvent>
#include <SDL.h>
#include <stdlib.h>
#include <Video.h>

static LPDWORD dwBootThreadID = 0; // This holds the ID of the thread that the emulation bootstrapper will run on
static HANDLE hBootThread; // Handle of our bootstrap thread

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    m_Debugger = new Debugger(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::ShowError(const char* errorMessage)
{
    qWarning(errorMessage);
    QErrorMessage *message = new QErrorMessage(this);
    message->showMessage(errorMessage);
}

void MainWindow::showDebugger()
{
    if (!m_Debugger->isVisible())
        m_Debugger->show();
    else
        m_Debugger->activateWindow();
}

void MainWindow::runEmulator()
{
    QAction *runAction = findChild<QAction*>("actionRun");
    QAction *stopAction = findChild<QAction*>("actionStop");

    runAction->setEnabled(false);
    stopAction->setEnabled(true);

    // Set the Window ID variable hack
    char * variable = (char *)malloc(50);
    sprintf(variable, "%s=%i","SDL_WINDOWID", (long)findChild<QWidget*>("m_RenderWidget")->winId());
    _putenv(variable);

    if (Init() == M64ERR_SUCCESS)
    {
        hBootThread = CreateThread(NULL, 0, Run, NULL, 0, dwBootThreadID);

        if (hBootThread == NULL)
            ShowError("Failed to run emulator bootstrap thread");
    }
    else
    {
        ShowError("Failed to initialize the core");
    }
}

void MainWindow::stopEmulator()
{
    QAction *runAction = findChild<QAction*>("actionRun");
    QAction *stopAction = findChild<QAction*>("actionStop");

    // First send the stop signal to the emulator
    CoreDoCommand(M64CMD_STOP, 0, NULL);

    // Wait for the emulator bootstrap thread to exit
    WaitForSingleObject(hBootThreadWaitEvent, INFINITE);

    // Now lets close the handle of our thread
    if (!CloseHandle(hBootThread))
        ShowError("Failed to close the handler for the bootstrap thread");

    runAction->setEnabled(true);
    stopAction->setEnabled(false);

    QWidget *widget = findChild<QWidget*>("m_RenderWidget");
    widget->update();
}

void MainWindow::resizeEvent(QResizeEvent * /*event*/)
{
    QWidget *widget = findChild<QWidget*>("m_RenderWidget");
    QToolBar *toolbar = findChild<QToolBar*>("mainToolbar");
    QMenuBar *menubar = findChild<QMenuBar*>("menuBar");

    int miscHeight = toolbar->size().height() + menubar->size().height();

    widget->setGeometry(0, 0,
                        this->size().width(),
                        this->size().height() - miscHeight);

    widget->updateGeometry();

    // Tell the Video core to update its backbuffer size
    SetDisplaySize(widget->size().width(), widget->size().height());
}
